﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using SistemaCenterQuimPost.Entidad;  //Usado para instanciar objetos de clase Producto y agilizar el filtrado de descripción.
using SistemaCenterQuimPost.Control; //Usado para validar textBox
using SistemaCenterQuimPost.Plantillas; //necesario para obtener fecha, nombre usuario etc,

using System.IO;    //3 referencias que son necesarias para el proceso de archivos.
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;


namespace SistemaCenterQuimPost.UI
{
    public partial class frmTraslado : SistemaCenterQuimPost.UI.frmGestionProductos
    {
        //-----------------------------ATRIBUTOS----------------------------
                                                      //atributos usados para la base de datos
        protected DataSet2TableAdapters.TrasladosTableAdapter trasladosTa;

        protected DataSet2TableAdapters.ProductosxTrasladoTableAdapter productosXTrasladosTa;

        protected string fechaActual;  //necesario para inicializar la interface con estos 2 datos.

        protected string nombreCajero;

        //objeto para serializar los RegistroUsuario y RegistroListaPrecio en formato binario
        protected BinaryFormatter aplicadorFormato = new BinaryFormatter(); //Clase que permite serializar objeto, es decir pasarlo a binario.
        

       
        // -----------------------------CONSTRUCTORES-----------------------------
        public frmTraslado()
        {
            InitializeComponent();
            
                                   //inicializamos adaptadores necesarios para est interface.
            trasladosTa = new DataSet2TableAdapters.TrasladosTableAdapter();

            productosXTrasladosTa = new DataSet2TableAdapters.ProductosxTrasladoTableAdapter();

            removerControles();  //se remueve los controles heredados que no necesitamos en esta interface, por diseño no se puede

            posicionarListBox(); //se posiciona los listBox, porque por herencia en el diseño no se puede.

            this.nombreCajero = ""; //inicializa estos 2 datos a un valor arbitrario.

            this.fechaActual = "";

            
        }

        public frmTraslado(int ancho, int alto) //frmGestiónProductos usan Administrador y Cajero, ambos usan diferentes 
        //tamaño de ventana. Al usar este formulario se reciben los tamaños de ventana ha usar en cada uno.
        {
            InitializeComponent();

            
            this.Width = ancho;
            this.Height = alto;
            this.MinimumSize = new System.Drawing.Size(ancho, alto); //Se establece el tamaño máximo y mínimo en pixeles.
            this.MaximumSize = new System.Drawing.Size(ancho, alto);

            

        }

        //------------------------------ESTADOS-------------------------------------

        private void frmTraslado_Load(object sender, EventArgs e)
        {
            estEsperandoOperacion();
        }

        //redefinido del padre.
        protected override void estEsperandoOperacion() //se redefine para que no cause conflicto. Acá no se usa
        {
            if (refrescarResgProductos) //si hace falta actualizar el refrescarResgProducto se realiza
            {
                ejecutarHiloActualizarResgProductos();

            }

            System.Windows.Forms.Control[] controlesHabilitados = { };
            System.Windows.Forms.Control[] controlesDeshabilitados = { lstProductosCodBarra, lstProductosDescripcion };
            System.Windows.Forms.Control[] controlesVisibles = { };
            System.Windows.Forms.Control[] controlesInvisibles = {lstProductosCodBarra, lstProductosDescripcion, lblError };

            habilitarControles(controlesHabilitados);
            deshabilitarControles(controlesDeshabilitados);
            visibleControles(controlesVisibles);
            invisibleControles(controlesInvisibles);

            errorProvider1.Clear();  //se borran los errores, si habian.
                        
            cboTurno.Focus();   //se deja el foco en txtCodBarra

            estadoDelFormulario = "estEsperandoOperacion";
        }

        //----------------METODOS VARIOS---------------------

        protected void removerControles()   //Eliminar los controles que heredé pero que no los voy a usar.
        {
            this.Controls.Remove(this.lblPrecioCosto);
            this.Controls.Remove(this.txtPrecioCosto);
            this.Controls.Remove(this.lblPrecioVenta);
            this.Controls.Remove(this.txtPrecioVenta);
            this.Controls.Remove(this.lblStockActual);
            this.Controls.Remove(this.txtStockActual);
            this.Controls.Remove(this.lblCantMinima);
            this.Controls.Remove(this.txtCantMinima);
            this.Controls.Remove(this.btnAgregar);
            this.Controls.Remove(this.btnEditar);
            this.Controls.Remove(this.lblEditar);
            this.Controls.Remove(this.lblAgregar);


            this.Controls.Remove(this.lblErrorPCosto);
            this.Controls.Remove(this.lblErrorPVenta);
            this.Controls.Remove(this.lblErrorStockActual);
            this.Controls.Remove(this.lblErrorCantMin);
            this.Controls.Remove(this.lblErrorDescripcion);
            
        }

        protected virtual void limpiarDatos() //Se deja todo los datos vacios, usado al inicio y cada nuevo traslado en la interface
        {
            
            this.cboTurno.Text = "";
            this.txtCodBarra.Text = "";
            this.txtDescripcion.Text = "";
            this.dgvProductos.Rows.Clear();

            
        }

        protected void posicionarListBox()  //usado para colocar a los lstBox en su lugar, ya que por herencia en t.Diseño no se puede.
        {
            lstProductosCodBarra.Location = new Point(62, 197);
            lstProductosDescripcion.Location = new Point(357, 197);
        }

        //Redefinido del padre
        protected override void actualizarResgProductos() //Se refresca el arrayList resgProductos
        {
            try
            {
                //(ALE) HACER EL FILL O COMO LO LLAMES ACA ABAJO
                //ProductosTa.FillByProductos1(centerQuimDs,...);
                productosTa.FillByNoGranel(centerQuimDs.Productos);

                resgProductos.Clear(); //Se vacia resgProductos (ArrayList)

                foreach (DataRow unaFila in centerQuimDs.Productos) //Se recorre todas las filas  del centerQuimDs.Productos y se cargan los productos al ArrayList
                {
                        resgProductos.Add(new Producto(Convert.ToString(unaFila[0]), Convert.ToString(unaFila[1])));
                    
                }

                refrescarResgProductos = false;

            }
            catch (IndexOutOfRangeException)
            {
                //si llega a ocurrir esta excepcion no se tiene en cuenta. Podría no haber productos cargados y lanzaría esta excepción.

            }
            catch (Exception ex)
            {
                //Por cualquier otra excepcion se informa el error, en este caso es un error grave.
                MessageBox.Show("La conexión a la base de datos no fué exitosa.\n\n Comuniquese con su desarrollador para solucionar el problema.\n\n" + ex.Message, "ERROR GRAVE - ACCESO A BASE DE DATO", MessageBoxButtons.OK, MessageBoxIcon.Error);

                //Si llega a ocurrir algún error grave se cierra el formulario 
                this.Close();
            }

        }

        protected override void cargarProductoPorCodigo(string unCodBarra) //busca producto con codigo de barra único (una coincidencia) encontrado en el oHiloFiltrarCodBarra y lo carga en el dgvProductos
        {
            try
            {
                //(ALE)HACER EL FILL O COMO LO LLAMES ACA ABAJO
                //ProductosTa.FillByProductos1(centerQuimDs,unCodBarra);
                productosTa.FillByCodigo(centerQuimDs.Productos, unCodBarra);

                dgvProductos.Rows.Add(centerQuimDs.Productos[0].codProducto, centerQuimDs.Productos[0].descripcion,0);

                txtCodBarra.Text = ""; //se borra el txtCodBarra y Descripción
                txtDescripcion.Text = ""; 

            }
            catch (IndexOutOfRangeException)
            {

            }
            catch (Exception ex)
            {
                //Por cualquier otra excepcion se informa el error, en este caso es un error grave.
                MessageBox.Show("La conexión a la base de datos no fué exitosa.\n\n Comuniquese con su desarrollador para solucionar el problema.\n\n" + ex.Message, "ERROR GRAVE - ACCESO A BASE DE DATO", MessageBoxButtons.OK, MessageBoxIcon.Error);

                //Si llega a ocurrir algún error grave se cierra el formulario 
                this.Close();
            }
        }

        protected override void cargarProductoPorDescripcion(string unaDescripcion)  //busca el producto por descripción en la base de datos y lo carga en el dgvProductos.
        {
            //(ALE) HACER EL FILL O COMO LO LLAMES ACA ABAJO
            productosTa.FillByNombre(centerQuimDs.Productos, unaDescripcion);

            //ARREGLAR ESTO. Se carga en el dgvProductos la consulta encontrada. 

            dgvProductos.Rows.Add(centerQuimDs.Productos[0].codProducto, centerQuimDs.Productos[0].descripcion,0);

            txtCodBarra.Text = ""; //se borra el txtCodBarra y Descripción
            txtDescripcion.Text = ""; 

        }

        protected override void resguardarProductoActual() //esta operación aunque se hereda, se deja vacia.
        {

        }

        //Redefinido del padre
        protected override void procesar() //se encapsulo en un método para usar cuando se presiona Enter con los textBox
        {
            if (formularioValido())
            {
                try
                {

                    DialogResult result = MessageBox.Show("¿Está seguro de realizar la operación de traslado? ", "CONFIRMACION TRASLADO", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                    if (result == DialogResult.Yes)
                    {
                        altaTraslado();
                        productosxTraslado();
                        redefenirStock();
                        crearArchivoTraslado(); //se crea el archivo de pedido y se deja en el post seleccionado.  //solo se ocupa en traslado de salida.
                        eliminarArchivo(); //solo se ocupa en traslado de entrada
                        MessageBox.Show("Traslado procesado con exito!!!", "AVISO", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        imprimir();

                        this.limpiarDatos();
                    }

                }
                catch (IndexOutOfRangeException)
                {

                }
                catch (Exception ex)
                {
                    //Por cualquier otra excepcion se informa el error, en este caso es un error grave.
                    MessageBox.Show("La conexión a la base de datos no fué exitosa.\n\n Comuniquese con su desarrollador para solucionar el problema.\n\n" + ex.Message, "ERROR GRAVE - ACCESO A BASE DE DATO", MessageBoxButtons.OK, MessageBoxIcon.Error);

                    //Si llega a ocurrir algún error en estado agregar 
                    this.Close();
                }

            }
            else
            {
                informarExistenciaError();
            }


        }


        //redefinido del padre
        protected override bool formularioValido()
        {

            validarTurno();

            validarGrilla();


            if ((errorProvider1.GetError(cboTurno) == "") & (errorProvider1.GetError(dgvProductos) == ""))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        
        protected void validarTurno()
        {
            if (cboTurno.Text.Trim() == "")
            {
                errorProvider1.SetError(cboTurno, "Turno: el campo se encuentra vacio\n\n");
            }
            else
            {
                errorProvider1.SetError(cboTurno, "");
            }
        }

        
        protected void validarGrilla() //recorre todo el dataGride y verifica que los datos se encuentren correctos, si alguno está incorrecto los pinta de blanco
        {
            bool grillaSinError = true;  //inicializa el booleano que controla si el dgvProductos tiene al menos un error.

            foreach (DataGridViewRow row in dgvProductos.Rows)
            {

                string tipo = Convert.ToString(row.Cells[1].Value).Substring(0, 1);  //obtiene si el tipo de producto en la fila, en base a la primera letra de la descripción

                if (tipo == "T" || (tipo == "D"))
                {
                    if ((new ValidarDatos().ValidarNaturalesPositivos("Fila:", Convert.ToString(row.Cells[2].Value).Trim())) == "") //No tiene error. El producto terminado o disuelto por cantidad.
                    {
                        row.Cells[2].Style.BackColor = Color.White;

                    }
                    else      //con error en producto terminado o disuelto por cantidad
                    {
                        row.Cells[2].Style.BackColor = Color.LightPink;

                        grillaSinError = false;
                    }

                }
                else
                {
                    if ((new ValidarDatos().validarRealesPositvosSinCero("Fila:", Convert.ToString(row.Cells[2].Value).Trim())) == "") //No tiene error. El producto base.
                    {
                        row.Cells[2].Style.BackColor = Color.White;

                    }
                    else  //con error en producto base
                    {
                        row.Cells[2].Style.BackColor = Color.LightPink;

                        grillaSinError = false;
                    }
                }

            }


            if (grillaSinError)
            {
                errorProvider1.SetError(dgvProductos, "");
            }
            else
            {
                errorProvider1.SetError(dgvProductos, "Algunos de los campos cantidad en la grilla no contiene datos válidos.");
            }

            if (dgvProductos.RowCount == 0)
            {
                errorProvider1.SetError(dgvProductos, "La grilla no contiene productos.");
            }

        }

        protected string obtenerNombreUsuarioActual()  //Dato necesario para obtener nombre de usuario
        {
            frmPlantillaPadre unFrm = (frmPlantillaPadre)this.MdiParent;
            return unFrm.getNombreUsuario();
        }

        protected int obtenerCodUsuarioActual()  //Dato necesarios para obtener codigo de usuario
        {
            frmPlantillaPadre unFrm = (frmPlantillaPadre)this.MdiParent;
            return unFrm.getCodUsuario();
        }

        protected string obtenerFechaActual()  //Dato necesario para la apertura de una caja.
        {
            frmPlantillaPadre unFrm = (frmPlantillaPadre)this.MdiParent;
            return unFrm.getFechaActual();
        }

        protected virtual void altaTraslado() //metodo virtual que inserta un nuevo registro en la base de traslados
        {

        }

        protected void productosxTraslado()
        {
            //obtenemos el ultimo numero de traslado
            int ultimoTraslado = trasladosTa.ScalarQueryTraslados().Value;

            //base.productosxTraslado();
            foreach (DataGridViewRow row in dgvProductos.Rows)//recorremos el datagride y cargamos las lineas
            {
                productosXTrasladosTa.InsertQueryProductosxTraslado(ultimoTraslado, row.Cells[0].Value.ToString(), row.Cells[1].Value.ToString(), Convert.ToDecimal(row.Cells[2].Value));
            }
        }

        protected virtual void imprimir() // metodo que llama a imprimir. solo es usado en trasladoSalida
        {

        }

        protected virtual void redefenirStock() //metodo virtual que actualiza el stock
        {

        }

        protected virtual void crearArchivoTraslado()
        {
            
        }

        protected virtual void eliminarArchivo()
        {
            
        }

        public void setFechaActual(string unaFecha)
        {
            this.fechaActual = unaFecha;
        }

        public void setNombreCajero(string unNombre)
        {
            this.nombreCajero = unNombre;
        }


    }
}
